﻿/* Copyright 2007-2008 dnAnalytics Project.
 *
 * Contributors to this file:
 * Marcus Cuda
 *
 * This file is part of dnAnalytics.  dnAnalytics is licensed under the 
 * Microsoft Public License. See License.txt for a complete copy of the
 * license.
 */

namespace dnAnalytics.LinearAlgebra.Decomposition
{
    internal class DenseHouseholder : AbstractHouseholder
    {
        private double[] mTau;

        public DenseHouseholder(Matrix matrix)
            : base(matrix)
        {
        }

        protected override void DoCompute()
        {
            mQ = new DenseMatrix(mRows, mRows);
            mTau = new double[mColumns];
            double[] q = ((DenseMatrix)mQ).Data;
            double[] r = ((DenseMatrix)mR).Data;

            SafeNativeMethods.d_qr_factor(mRows, mColumns, r, mTau, q);
        }

        protected override void DoSolve(Matrix b, Matrix result)
        {
            if (b is DenseMatrix && result is DenseMatrix)
            {
                SafeNativeMethods.d_qr_solve(mRows, mColumns, b.Columns, ((DenseMatrix)mR).Data, ((DenseMatrix)b).Data, mTau, ((DenseMatrix)result).Data);
            }
            else if (b is DenseMatrix)
            {
                DenseMatrix tmp = new DenseMatrix(result);
                SafeNativeMethods.d_qr_solve(mRows, mColumns, b.Columns, ((DenseMatrix)mR).Data, ((DenseMatrix)b).Data, mTau, (tmp).Data);
                tmp.CopyTo(result);
            }
            else if (result is DenseMatrix)
            {
                DenseMatrix tmp = new DenseMatrix(b);
                SafeNativeMethods.d_qr_solve(mRows, mColumns, b.Columns, ((DenseMatrix)mR).Data, (tmp).Data, mTau, ((DenseMatrix)result).Data);
            }
            else
            {
                DenseMatrix tmpB = new DenseMatrix(b);
                DenseMatrix tmpResult = new DenseMatrix(result);
                SafeNativeMethods.d_qr_solve(mRows, mColumns, b.Columns, ((DenseMatrix)mR).Data, tmpB.Data, mTau, tmpResult.Data);
            }
        }

        protected override void DoSolve(Vector b, Vector result)
        {
            SafeNativeMethods.d_qr_solve(mRows, mColumns, 1, ((DenseMatrix)mR).Data, ((DenseVector)b).Data, mTau, ((DenseVector)result).Data);
        }
    }
}